package model.primitive;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import javax.vecmath.Point2d;
import javax.vecmath.Point2f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;

import model.ray.Ray;
import model.shader.Shader;
import camera.Camera;

public class GenericMesh extends Primitive{
	public List<TriangleOld> triangles;
	public List<TriangleOld> triOff;
	public Map<Point3d, Point3d> normals;
	public Map<Point3d, Point2d> uvs;
	public Vector3d normal;
	
	public GenericMesh(Shader shader, String name) {
		super(shader, name);
	}
	
	public GenericMesh(Shader shader, String name, List<TriangleOld> triangles2,
			Map<Point3d, Point3d> normals, Map<Point3d, Point2d> uvs) {
		super(shader, name);
		this.triangles = triangles2;
		this.triOff = new ArrayList<TriangleOld>();
		this.triOff.addAll(triangles);
		this.normals = normals;
		this.uvs = uvs;
	}

	public List<TriangleOld> getTriangles() {
		return triangles;
	}
	public void setTriangles(List<TriangleOld> triangles) {
		this.triangles = triangles;
	}
	
//	public Vector3d getNormal() {
//		return normal;
//	}
//	public void setNormal(Vector3d normal) {
//		this.normal = normal;
//	}
//	public Uvs getUvs() {
//		return uvs;
//	}
//	public void setUvs(Uvs uvs) {
//		this.uvs = uvs;
//	}
	
	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("Generic-mesh\n");
		sb.append("name: " + getName()).append("\n");
		sb.append("Triangles: \n");
		for (TriangleOld t: this.triangles) {
			sb.append(t).append("\n");
			
		}
	
		return sb.toString();
	}

	@Override
	public List<Point3d> getIntersections(Ray ray) {
		Point3d curr, closer;
		Double dist, currdist;
		dist = null;
		curr = null;
		closer = null;
		
		ArrayList<Point3d> intersections = new ArrayList<Point3d>();

		//Ahora retona la lista de tods las intersecciones
		for (TriangleOld triangle : this.triangles) {
//			intersections.addAll(triangle.getIntersections(ray));
			
			List<Point3d> list_aux = triangle.getIntersections(ray);
			
			if (list_aux != null) {
				curr = list_aux.get(0);
				triOff.remove(triangle);
			}
			
			if (dist == null && curr != null) {
				dist = ray.getDistance(curr);
				closer = curr;
				this.normal = triangle.getNormal(curr);
				break;
			} else {	
				if (curr != null) {
					currdist = ray.getDistance(curr);
					
					if (currdist < dist) {
						dist = currdist;
						closer = curr;
						this.normal = triangle.getNormal(curr);
					}
				}
			}
		}
		
		if (closer != null) {
			intersections.add(closer);
		}
		
		return intersections;
	}

	@Override
	public void translate(Point3d pos) {
		for (TriangleOld t: this.triangles) {
			t.translate(pos);
		}
	}

	@Override
	public Vector3d getNormal(Point3d pos) {
		return new Vector3d(this.normal);
	}

	@Override
	public void rotatex(Double degree) {
		if (degree!=null);
		for (TriangleOld t: this.triangles)
			t.rotatex(degree);
	}

	@Override
	public void rotatey(Double degree) {
		if (degree!=null);
		for (TriangleOld t: this.triangles)
			t.rotatey(degree);
	}

	@Override
	public void rotatez(Double degree) {
		if (degree!=null);
		for (TriangleOld t: this.triangles)
			t.rotatez(degree);
	}

	@Override
	public void scalex(Double sx) {
		if (sx!=null && sx > 0);
			for (TriangleOld t: this.triangles)
				t.scaleu(sx);
	}

	@Override
	public void scaley(Double sy) {
		if (sy!=null && sy > 0);
			for (TriangleOld t: this.triangles)
				t.scaleu(sy);
	}

	@Override
	public void scalez(Double sz) {
		if (sz!=null && sz > 0);
			for (TriangleOld t: this.triangles)
				t.scaleu(sz);
	}

	@Override
	public void scaleu(Double su) {
		if (su!=null && su > 0);
			for (TriangleOld t: this.triangles)
				t.scaleu(su);
		
	}

	@Override
	public Point2f getUV(Point3d p) {
		// TODO Auto-generated method stub
		return null;
	}

	public static void sortTrianglesByCameraDistance( List<TriangleOld> triangles, Camera camera) {
		for( TriangleOld triangle : triangles ) {
			triangle.setDistance(camera.eye);
		}
		Collections.sort(triangles);
	}
	
}
